#include "Stackle_For_Reducer.c"

void Translator(Stackle_For_Char_Ptr Stack_For_Char,char* expr)
{
    int i = 0;
    for(;expr[i] != '\0';i++)
    {
        if(expr[i] != '+')
        {
            Stackle_For_Char_Push(Stack_For_Char,expr[i]);
        }
    }
}

void Permutation_11(Node* head,int order)
{
    int length = Get_Length(head);
    int Counter = 1;
    Node* cur = head->next;
    for(;Counter != order;cur = cur->next)
    {
        Counter++;
    }
    insertNode(head,cur->coefficience,cur->exp[0],'0','0');
}

void Permutation_22(Node* head,int order)
{
    int length = Get_Length(head);
    int Counter = 1;
    Node* cur = head->next;
    for(;Counter != order;cur = cur->next)
    {
        Counter++;
    }
    insertNode(head,cur->coefficience,'0',cur->exp[1],'0');
}

void Permutation_33(Node* head,int order)
{
    int length = Get_Length(head);
    int Counter = 1;
    Node* cur = head->next;
    for(;Counter != order;cur = cur->next)
    {
        Counter++;
    }
    insertNode(head,cur->coefficience,'0','0',cur->exp[2]);
}

void Permutation_12(Node* head,int order)
{
    int length = Get_Length(head);
    Node* cur = head->next;
    int Counter = 1;
    for(;Counter != order;cur = cur->next)
    {
        Counter++;
    }
    insertNode(head,cur->coefficience,cur->exp[1],cur->exp[0],'0');
}

void Permutation_13(Node* head,int order)
{
    int length = Get_Length(head);
    Node* cur = head->next;
    int Counter = 1;
    for(;Counter != order;cur = cur->next)
    {
        Counter++;
    }
    insertNode(head,cur->coefficience,cur->exp[2],'0',cur->exp[0]);
}

void Permutation_23(Node* head,int order)
{
    int length = Get_Length(head);
    Node* cur = head->next;
    int Counter = 1;
    for(;Counter != order;cur = cur->next)
    {
        Counter++;
    }
    insertNode(head,cur->coefficience,'0',cur->exp[2],cur->exp[1]);
}

void Reducer(Node* head)
{
    int kind = 0;
    Stackle_For_Reducer_Ptr Reducer_Stack = Stackle_For_Reducer_Init();
    Node* Eyes;
    Node* PenPoint;
    Eyes = head->next;
    for(;Eyes != NULL;Eyes = Eyes->next)
    {
        kind++;
        PenPoint = Eyes->next;
        if(PenPoint != NULL)
        {
            for(;PenPoint != NULL;PenPoint = PenPoint->next)
            {
                if((Eyes->exp[0] == PenPoint->exp[0])&&(Eyes->exp[1] == PenPoint->exp[1])&&(Eyes->exp[2] == PenPoint->exp[2]))
                {
                    Stackle_For_Reducer_Push(Reducer_Stack,PenPoint);
                }
            }
        }
        for(;Reducer_Stack->top != NULL;Stackle_For_Reducer_Pop(Reducer_Stack))
        {
            Eyes->coefficience += Reducer_Stack->top->term_ptr->coefficience;
            deleteNode(head,Reducer_Stack->top->term_ptr->order);
        }
    }
}

void Print_Sequence(Node* head)
{
    int i = 1;
    Node* temp = head->next;
    for(;temp->next != NULL;temp = temp->next)
    {
        if(i!=1) printf("+");
        printf("%d*",temp->coefficience);
        printf("%c",temp->exp[0]);
        printf("%c",temp->exp[1]);
        printf("%c ",temp->exp[2]);
        i++;
    }
    printf("+",temp->order);
    printf("%d*",temp->coefficience);
    printf("%c",temp->exp[0]);
    printf("%c",temp->exp[1]);
    printf("%c\n",temp->exp[2]);
}

void Caculator(Node* head,Stackle_For_Char_Ptr Stack)
{
    Char_Link_Ptr Penpoint = Stack->base;
    int length = Get_Length(head);
    if(length == 1)
    {
        for(Penpoint = Stack->base;Penpoint->next != Stack->top;Penpoint = Penpoint->next->next)
        {
            if((Penpoint->text == '1')&&(Penpoint->next->text == '1')) Permutation_11(head,1);
            if((Penpoint->text == '2')&&(Penpoint->next->text == '2')) Permutation_22(head,1);
            if((Penpoint->text == '3')&&(Penpoint->next->text == '3')) Permutation_33(head,1);
            if((Penpoint->text == '1')&&(Penpoint->next->text == '2')) Permutation_12(head,1);
            if((Penpoint->text == '1')&&(Penpoint->next->text == '3')) Permutation_13(head,1);
            if((Penpoint->text == '2')&&(Penpoint->next->text == '3')) Permutation_23(head,1);
        }
        if((Penpoint->text == '1')&&(Penpoint->next->text == '1')) Permutation_11(head,1);
        if((Penpoint->text == '2')&&(Penpoint->next->text == '2')) Permutation_22(head,1);
        if((Penpoint->text == '3')&&(Penpoint->next->text == '3')) Permutation_33(head,1);
        if((Penpoint->text == '1')&&(Penpoint->next->text == '2')) Permutation_12(head,1);
        if((Penpoint->text == '1')&&(Penpoint->next->text == '3')) Permutation_13(head,1);
        if((Penpoint->text == '2')&&(Penpoint->next->text == '3')) Permutation_23(head,1);
        deleteNode(head,1);
    }
    else
    {
        int Counter = 1;
        for(;Counter <= length;Counter++)
        {
            for(Penpoint = Stack->base;Penpoint->next != Stack->top;Penpoint = Penpoint->next->next)
            {
                if((Penpoint->text == '1')&&(Penpoint->next->text == '1')) Permutation_11(head,Counter);
                if((Penpoint->text == '2')&&(Penpoint->next->text == '2')) Permutation_22(head,Counter);
                if((Penpoint->text == '3')&&(Penpoint->next->text == '3')) Permutation_33(head,Counter);
                if((Penpoint->text == '1')&&(Penpoint->next->text == '2')) Permutation_12(head,Counter);
                if((Penpoint->text == '1')&&(Penpoint->next->text == '3')) Permutation_13(head,Counter);
                if((Penpoint->text == '2')&&(Penpoint->next->text == '3')) Permutation_23(head,Counter);
            }
            if((Penpoint->text == '1')&&(Penpoint->next->text == '1')) Permutation_11(head,Counter);
            if((Penpoint->text == '2')&&(Penpoint->next->text == '2')) Permutation_22(head,Counter);
            if((Penpoint->text == '3')&&(Penpoint->next->text == '3')) Permutation_33(head,Counter);
            if((Penpoint->text == '1')&&(Penpoint->next->text == '2')) Permutation_12(head,Counter);
            if((Penpoint->text == '1')&&(Penpoint->next->text == '3')) Permutation_13(head,Counter);
            if((Penpoint->text == '2')&&(Penpoint->next->text == '3')) Permutation_23(head,Counter);
        }
        for(int i = length;i >= 1;i--)
        {
            deleteNode(head,i);
        }
    }
}

void main()
{
    Node* head = initList();
    Stackle_For_Char_Ptr Char_Stack = Stackle_For_Char_Init();
    char expr[] = "12+23";
    Translator(Char_Stack,expr);
    insertNode(head,1,'a','b','c');
    Caculator(head,Char_Stack);
    Reducer(head);
    Print_Sequence(head);
    Caculator(head,Char_Stack);
    Reducer(head);
    Print_Sequence(head);
    Caculator(head,Char_Stack);
    Reducer(head);
    Print_Sequence(head);
    Caculator(head,Char_Stack);
    Reducer(head);
    Print_Sequence(head);
    Reducer(head);
}